package main

import (
	"context"
	"fmt"
	"github.com/olivere/elastic/v7"
	"go.uber.org/zap"
	"log"
	"os"
	"regexp"
	"runtime"
	"time"
)

var (
	esCli 			*elastic.Client
	mesChan 		chan *EsStruct
	wechChan 		chan *EsStruct
	saveEs 			chan int
	buffer 			[][]*EsStruct			//开几个buffer, 每个buffer容量为多少，配置文件里指定
	nIdx 			[]int					//上面个buffer的游标
	Tianqi			string					//天气
	TianqiBak 		string					//防止天气刷新不出来，备份上一次获取的天气
	FileNames 		Resource
	sugarLogger 	*zap.SugaredLogger
	aliasIndex 		string
	aliasIndex1 	string
	Rrexp			[]*regexp.Regexp		//反向匹配表
	Mrexp   		[]*regexp.Regexp		//正向匹配表
)

func Init(ctx context.Context) {
	//读取配置文件信息
	ReadYaml(&FileNames)
	aliasIndex = FileNames.Elasticsearch.Index+"_alias"
	aliasIndex1 = FileNames.Elasticsearch.Wechat+"_alias"
	InitLogger()
	defer sugarLogger.Sync()
	sugarLogger.Infof("当前配置文件信息: %v", FileNames)
	esLogFile, err := os.OpenFile(FileNames.OutConfigLog.LogName, os.O_APPEND|os.O_CREATE, 0644)
	if err != nil {
		fmt.Printf("%s 日志文件创建失败\n", FileNames.OutConfigLog.LogName)
	}
	if FileNames.Elasticsearch.User == "" {
		esCli, err = elastic.NewClient(
			elastic.SetSniff(false),
			elastic.SetURL(FileNames.Elasticsearch.Address),
			elastic.SetErrorLog(log.New(esLogFile, "", log.LstdFlags)), 	// 设置错误日志输出
		)
	} else {
		esCli, err = elastic.NewClient(
			elastic.SetSniff(false),
			elastic.SetURL(FileNames.Elasticsearch.Address),
			elastic.SetBasicAuth(FileNames.Elasticsearch.User, FileNames.Elasticsearch.Password),
			elastic.SetErrorLog(log.New(esLogFile, "", log.LstdFlags)), 	// 设置错误日志输出
		)
	}
	esCli, err = elastic.NewClient(
		elastic.SetSniff(false),
		elastic.SetURL(FileNames.Elasticsearch.Address),
		elastic.SetErrorLog(log.New(esLogFile, "", log.LstdFlags)), 	// 设置错误日志输出
	)
	if err != nil {
		sugarLogger.Panicf("es连接失败: %s", err)
	}
	InitEsBuffer()			//初始化ESBuffer
	InitRegexpTable()		//编译正则匹配数组表
	InitTianMap()  			//初始化地区编号
	var ok bool
	FileNames.WeatherCode, ok = SearchAddress()
	if ! ok {
		sugarLogger.Errorf("获取天气的地址: %s 不正确, 请填写什么省,或者什么市,或者什么县, 或者什么区", FileNames.AddressWeather)
	}
	CreateIndex(FileNames.Elasticsearch.Index, FileNames.Elasticsearch.Shards, FileNames.Elasticsearch.Replicas)		//没有日志索引则创建索引
	CreateIndex(FileNames.Elasticsearch.Wechat, FileNames.Elasticsearch.Shards, FileNames.Elasticsearch.Replicas)		//没有微信日志告警记录索引则创建索引
	go getTianqi(ctx)
}

func getTianqi(ctx context.Context)  {
	for {
		select {
		case <-ctx.Done():
			return
		default:
			getTian()												//每隔1小时获取天气
			for i, k :=0, len(FileNames.Wechat); i < k; i++ {		//每隔一小时获取微信token
				Get_AccessToken(&FileNames.Wechat[i])
			}
			sugarLogger.Info("goroutine数量为: ", runtime.NumGoroutine())
			time.Sleep(time.Hour)
		}
	}
}

func InitEsBuffer() {
	mesChan, wechChan, saveEs = make(chan *EsStruct, 1000000), make(chan *EsStruct, 1000000), make(chan int, FileNames.EsPerformance.BufferSlot)
	buffer, nIdx = make([][]*EsStruct,FileNames.EsPerformance.BufferSlot, FileNames.EsPerformance.BufferSlot), make([]int, FileNames.EsPerformance.BufferSlot)
	for i:=0; i<FileNames.EsPerformance.BufferSlot; i++ {
		buffer[i] = make([]*EsStruct, FileNames.EsPerformance.BufferSize, FileNames.EsPerformance.BufferSize)
	}
	for i:=0; i<FileNames.EsPerformance.BufferSlot; i++ {saveEs <- i}
}

func InitRegexpTable() {
	for i, k:=0, len(FileNames.RMonitorStr); i<k; i++ {
		Rrexp = append(Rrexp, regexp.MustCompile(FileNames.RMonitorStr[i]))
	}
	for i, k:=0, len(FileNames.MonitorStr); i<k; i++ {
		Mrexp = append(Mrexp, regexp.MustCompile(FileNames.MonitorStr[i]))
	}
}